package cn.bugstack.springframework.core.io;

import cn.bugstack.springframework.util.ClassUtils;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

/**
 * @Description
 * @Classname ClassPathResource
 * @Date 2024/3/22 20:57
 * @Created by aazhao
 */
/**
 * 用于表示类路径资源的类。
 *
 * 这个类允许通过类路径路径来访问资源，提供了获取资源输入流的方法。
 */
public class ClassPathResource implements Resource {

    private final String path; // 资源的路径
    private ClassLoader classLoader; // 用于加载资源的类加载器

    /**
     * 构造函数，创建一个类路径资源实例。
     *
     * @param path 资源的路径，不能为空。
     * @throws RuntimeException 如果路径为null，则抛出此异常。
     */
    public ClassPathResource(String path) {
        this(path, (ClassLoader) null);
    }

    /**
     * 构造函数，创建一个类路径资源实例，允许指定类加载器。
     *
     * @param path 资源的路径，不能为空。
     * @param classLoader 用于加载资源的类加载器，如果为null，则使用默认的类加载器。
     * @throws RuntimeException 如果路径为null，则抛出此异常。
     */
    public ClassPathResource(String path, ClassLoader classLoader) {
        if (path == null) {
            throw new RuntimeException("Path must not be null");
        }
        this.path = path;
        this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
    }

    /**
     * 获取资源的输入流。
     *
     * @return 资源的输入流。
     * @throws IOException 如果资源不存在，则抛出此异常。
     */
    @Override
    public InputStream getInputStream() throws IOException {
        // 会尝试从给定路径加载资源文件，并返回一个输入流以读取该资源文件的内容。
        // 在这里，path 是资源文件的路径，通常是相对于 classpath 的路径。
        // 需要注意的是，如果指定路径的资源文件不存在或无法访问，该方法将返回 null。
        InputStream is = classLoader.getResourceAsStream(path);
        if (is == null) {
            throw new FileNotFoundException(this.path + " cannot be opened because it does not exist");
        }
        return is;
    }
}

